package com.fanfan.shiroadmin.modules.sys.auth;

import com.alibaba.fastjson.JSONObject;
import com.fanfan.shiroadmin.common.web.entiy.BaseEntity;
import com.fanfan.shiroadmin.modules.sys.constant.SysConstant;
import com.fanfan.shiroadmin.modules.sys.entity.SysMenuEntity;
import com.fanfan.shiroadmin.modules.sys.entity.SysUserEntity;
import com.fanfan.shiroadmin.modules.sys.service.IShiroService;
import com.fanfan.shiroadmin.modules.sys.service.ShiroCacheService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 自定义shiro配置
 * @author DunFan.Liao
 * @date 2021/8/19 10:11
 */
@Component
public class CustomAuthRealm extends AuthorizingRealm
{

    @Resource(name = IShiroService.BEAN_ID)
    private IShiroService shiroService;

    @Resource(name = ShiroCacheService.BEAN_ID)
    private ShiroCacheService shiroCacheService;
    /**
    * 功能描述：给登陆成功的用户授权
    * @param principal 用户信息
    * @return AuthorizationInfo 授权信息
    * @author DunFan.Liao
    * @date 2021/8/19 10:34
    */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal)
    {
        SysUserEntity user = (SysUserEntity)principal.getPrimaryPrincipal();
        Set<String> permissions = new HashSet<>();
        if (user != null){
            // 1.拿到用户权限列表
            if (SysConstant.ADMIN_USER_ID.equals(user.getId()))
            {
                // 缓存用户权限菜单
                shiroCacheService.addUserMenuCache(user);
                // 获取资源权限
                permissions = shiroCacheService.addUserRsUrlCache(user);

            }
            else
            {

            }
            // 2.给当前用户授权
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            info.setStringPermissions(permissions);
            return info;
        }
        return null;
    }

    @Override
    public boolean supports(AuthenticationToken token)
    {
        return token instanceof SysAuthToken;
    }

    /**
    * 功能描述：认证登陆用户信息（登陆时使用）
    * @param token 登陆的token
    * @return AuthenticationInfo 认证信息
    * @author DunFan.Liao
    * @date 2021/8/19 10:42
    */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException
    {
        String accessToken = (String) token.getPrincipal();
        JSONObject tokenData = shiroService.queryUserByToken(accessToken);
        if (tokenData.isEmpty())
        {
            throw new IncorrectCredentialsException("token失效，请重新登录");
        }
        SysUserEntity user = tokenData.getObject("user",SysUserEntity.class);
        // 账号锁定
        if (SysConstant.LOCK_STATE.equals(user.getUserSts()))
        {
            throw new LockedAccountException("账号已被锁定,请联系管理员");
        }

        return new SimpleAuthenticationInfo(user,accessToken,getName());
    }
}
